package controller;

import java.util.Collections;
import java.util.List;

import model.UseCaseModel;
import model.UseCaseModelImplemention;

import org.svenson.JSON;
import org.svenson.JSONParser;

import config.Config;
import config.Parser;
import controller.data.SuccessResponse;
import controller.data.commentDocumentation.CommentDocumentationRequest;
import controller.data.createNewDocumentation.CreateNewDocumentationRequest;
import controller.data.createNewDocumentation.IdResponse;
import controller.data.editDocumentation.EditDocumentationRequest;
import controller.data.rateDocumentation.RateDocumentationRequest;
import controller.data.readDocumentation.ReadDocumentationRequest;
import controller.data.readDocumentation.ReadDocumentationResponse;
import controller.data.searchRevision.SearchRevisionRequest;
import controller.data.searchRevision.SearchRevisionResponse;
import controller.factorys.IdResponseFactory;
import controller.factorys.SuccessResponseFactory;

public class UseCaseControllerImplementation implements UseCaseController {

	private final UseCaseModel model;
	private String id;
	private final Parser parser;
	private ReadDocumentationRequest readDocumentationRequest;

	public UseCaseControllerImplementation() {
		model = new UseCaseModelImplemention();
		id = "";
		parser = new Parser();
	}

	public List<ReadDocumentationResponse> readDocumentation(
			ReadDocumentationRequest request) {
		this.readDocumentationRequest = request;
		String jsonRequest = JSON.defaultJSON().forValue(request);
		String jsonResponse = model.readDocumentation(jsonRequest);
		if (jsonResponse != null && !jsonResponse.isEmpty()) {
			List<ReadDocumentationResponse> response = parser
					.parseReadDocumentResponseList(jsonResponse);
			return response;
		} else {
			return Collections.emptyList();
		}
	}

	public List<ReadDocumentationResponse> nextDocumentationPage() {
		readDocumentationRequest.nextDocumentationPage();
		return readDocumentation(readDocumentationRequest);
	}

	public List<ReadDocumentationResponse> previousDocumentationPage() {
		readDocumentationRequest.previousDocumentationPage();
		return readDocumentation(readDocumentationRequest);
	}

	public boolean isFirstPage() {
		return readDocumentationRequest.getSkipDocuments() == 0;
	}

	public boolean hasNextPage() {
		String category = readDocumentationRequest.getCategory();
		String javaelement = readDocumentationRequest.getJavaelement();
		int skipDocuments = readDocumentationRequest.getSkipDocuments();
		ReadDocumentationRequest next = new ReadDocumentationRequest(category,
				javaelement, skipDocuments);
		next.nextDocumentationPage();
		if (readDocumentation(next).size() > 0) {
			next.previousDocumentationPage();
			return true;
		}
		next.previousDocumentationPage();
		return false;
	}

	public String commentDocumentation(CommentDocumentationRequest request) {
		if (request == null || request.getId() == null
				|| request.getComment() == null) {
			return "Comment not added";
		}
		String jsonRequest = JSON.defaultJSON().forValue(request);
		String jsonResponse = model.commentDocumentation(jsonRequest);
		if (jsonResponse != null && !jsonResponse.isEmpty()) {
			return createSuccessResponse(jsonResponse).getResponse();
		} else {
			return Config.NO_CONNECTION;
		}
	}

	public String createNewDocumentation(CreateNewDocumentationRequest request) {
		if (request == null) {
			return "null";
		}
		String jsonRequest = JSON.defaultJSON().forValue(request);
		String jsonResponse = model.createNewDocumentation(jsonRequest);
		if (jsonResponse != null && !jsonResponse.isEmpty()) {
			return createIdResponse(jsonResponse).getId();
		} else {
			return Config.NO_CONNECTION;
		}
	}

	public String rateDocumentation(RateDocumentationRequest request) {
		String jsonRequest = JSON.defaultJSON().forValue(request);
		String jsonResponse = model.rateDocumentation(jsonRequest);
		if (jsonResponse != null && !jsonResponse.isEmpty()) {
			return createSuccessResponse(jsonResponse).getResponse();
		} else {
			return Config.NO_CONNECTION;
		}
	}

	public String editDocumentation(EditDocumentationRequest request) {
		String jsonRequest = JSON.defaultJSON().forValue(request);
		String jsonResponse = model.editDocumentation(jsonRequest);
		if (jsonResponse != null && !jsonResponse.isEmpty()) {
			return createSuccessResponse(jsonResponse).getResponse();
		} else {
			return Config.NO_CONNECTION;
		}
	}

	public List<SearchRevisionResponse> searchRevision(
			SearchRevisionRequest request) {
		String jsonRequest = JSON.defaultJSON().forValue(request);
		String jsonResponse = model.searchRevision(jsonRequest);
		if (jsonResponse != null) {
			List<SearchRevisionResponse> s = parser
					.parseSearchResponseList(jsonResponse);
			return s;
		} else {
			return Collections.emptyList();
		}
	}

	private SuccessResponse createSuccessResponse(String jsonResponse) {
		JSONParser parser = new JSONParser();
		parser.addObjectFactory(new SuccessResponseFactory());
		return parser.parse(SuccessResponse.class, jsonResponse);
	}

	private IdResponse createIdResponse(String jsonResponse) {
		JSONParser parser = new JSONParser();
		parser.addObjectFactory(new IdResponseFactory());
		return parser.parse(IdResponse.class, jsonResponse);
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}
}
